package com.right.netty.server;

import com.right.factory.PackageFactory;
import com.right.handler.ChannelEventHandler;
import com.right.handler.ExceptionHandler;
import com.right.handler.LogHandler;
import com.right.netty.ConnectorConfiguration;
import com.right.netty.codes.PackageDecoder;
import com.right.netty.codes.PackageEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;

import java.nio.charset.Charset;

/**********************************************
 * @author pillar
 * @date 2018/3/22
 **********************************************/
public class ServerChannelInitializer<C extends Channel, G extends ConnectorConfiguration> extends ChannelInitializer<C> {
    private final G configuration;
    private final EventLoopGroup workerGroup;
    private final PackageFactory packageFactory;
    private final ChannelHandler[] customChannelHandlers;
    private final PackageEncoder userEncoder;

    public ServerChannelInitializer(
            G configuration,
            EventLoopGroup workerGroup,
            PackageFactory packageFactory,
            ChannelHandler... customChannelHandlers) {
        this.configuration = configuration;
        this.workerGroup = workerGroup;
        this.packageFactory = packageFactory;
        this.customChannelHandlers = customChannelHandlers;
        this.userEncoder = new PackageEncoder();
    }

    @Override
    protected void initChannel(C ch) throws Exception {
        final ChannelPipeline pipeline = ch.pipeline();

        ByteBuf bytBufer = Unpooled.copiedBuffer("&&".getBytes());
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024,bytBufer));
        pipeline.addLast("userDecoder", new PackageDecoder());
        pipeline.addLast("userEncoder", this.userEncoder);

        if (configuration.isLoggingHandler()) {
            pipeline.addLast(workerGroup,"logHandler", new LogHandler(configuration.getLogLevel()));
        }
        pipeline.addLast(workerGroup,"readTimeoutHandler",new ReadTimeoutHandler(60 * 10));
        pipeline.addLast(workerGroup,"writeTimeoutHandler",new WriteTimeoutHandler(60 * 10));
        if (customChannelHandlers != null) {
            pipeline.addLast(workerGroup, customChannelHandlers);
        }
        pipeline.addLast("eventHandler", new ChannelEventHandler());

        pipeline.addLast("exception",new ExceptionHandler());
    }

}
